package com.voe;

import com.voe.callback.AudioDeviceObserver;
import com.voe.callback.AudioTransport;
import com.voe.common.OutputParam;
import com.voe.common.ReturnValue;
import com.voe.common.Utility;

public class AudioDeviceModule {
	
	//[start] apis

	public enum ErrorCode {

		kAdmErrNone(0), kAdmErrArgument(1);

		public static ErrorCode fromValue(int value) {
			for (int i=0;i<ErrorCode.values().length;i++) {
				if(ErrorCode.values()[i].getValue() == value)
					return ErrorCode.values()[i];
			}
			return null;
		}

		/**
		 * Constructor.
		 */
		private ErrorCode(int value) {
			this.value = value;
		}

		/**
		 * Get the value.
		 * 
		 * @return the value
		 */
		public int getValue() {
			return value;
		}

		private final int value;
	}

	public enum AudioLayer {
		
		kPlatformDefaultAudio(0),
		kWindowsWaveAudio(1), 
		kWindowsCoreAudio(2), 
		kLinuxAlsaAudio(3), 
		kLinuxPulseAudio(4),
		kDummyAudio(5);

		public static AudioLayer fromValue(int value) {
			for (int i=0;i<AudioLayer.values().length;i++) {
				if(AudioLayer.values()[i].getValue() == value)
					return AudioLayer.values()[i];
			}
			return null;
		}


		/**
		 * Constructor.
		 */
		private AudioLayer(int value) {
			this.value = value;
		}

		/**
		 * Get the value.
		 * 
		 * @return the value
		 */
		public int getValue() {
			return value;
		}

		private final int value;
	}

	public enum WindowsDeviceType {
		kDefaultCommunicationDevice(-1), kDefaultDevice(-2);

		public static WindowsDeviceType fromValue(int value) {
			for (int i=0;i<WindowsDeviceType.values().length;i++) {
				if(WindowsDeviceType.values()[i].getValue() == value)
					return WindowsDeviceType.values()[i];
			}
			return null;
		}

		/**
		 * Constructor.
		 */
		private WindowsDeviceType(int value) {
			this.value = value;
		}

		/**
		 * Get the value.
		 * 
		 * @return the value
		 */
		public int getValue() {
			return value;
		}

		private final int value;
	}

	public enum BufferType {
		kFixedBufferSize(0), kAdaptiveBufferSize(1);

		public static BufferType fromValue(int value) {
			for (int i=0;i<BufferType.values().length;i++) {
				if(BufferType.values()[i].getValue() == value)
					return BufferType.values()[i];
			}
			return null;
		}

		/**
		 * Constructor.
		 */
		private BufferType(int value) {
			this.value = value;
		}

		/**
		 * Get the value.
		 * 
		 * @return the value
		 */
		public int getValue() {
			return value;
		}

		private final int value;
	}

	public enum ChannelType {
		kChannelLeft(0), kChannelRight(1), kChannelBoth(2);

		public static ChannelType fromValue(int value) {
			for (int i=0;i<ChannelType.values().length;i++) {
				if(ChannelType.values()[i].getValue() == value)
					return ChannelType.values()[i];
			}
			return null;
		}

		/**
		 * Constructor.
		 */
		private ChannelType(int value) {
			this.value = value;
		}

		/**
		 * Get the value.
		 * 
		 * @return the value
		 */
		public int getValue() {
			return value;
		}

		private final int value;
	}

	public static AudioDeviceModule createInstance(int id, AudioLayer audioLayer) {

		return new AudioDeviceModule(CreateAudioDeviceModule(id,
				audioLayer.getValue()));
	}

	// Retrieve the currently utilized audio layer
	public int activeAudioLayer(ReturnValue<AudioLayer> audioLayer) {
		OutputParam output = new OutputParam();
		int result = ActiveAudioLayer(_p, output);
		audioLayer.setValue(AudioLayer.fromValue((Integer) output.getObject()[0]));
		return result;
	}

	// Error handling
	public int lastError() {
		return LastError(_p);
	}

	public int registerEventObserver(AudioDeviceObserver eventCallback) {
		Utility.throwNullPointerException(eventCallback, "eventCallback");
		return RegisterEventObserver(_p, eventCallback);
	}

	// Full-duplex transportation of PCM audio
	public int registerAudioCallback(AudioTransport audioCallback) {
		Utility.throwNullPointerException(audioCallback, "audioCallback");
		return RegisterAudioCallback(_p, audioCallback);
	}

	// Main initialization and termination
	public int init() {
		return Init(_p);
	}

	public int terminate() {
		return Terminate(_p);
	}

	public boolean initialized() {
		return Initialized(_p);
	}

	// Device enumeration
	public short playoutDevices() {
		return PlayoutDevices(_p);
	}

	public short recordingDevices() {
		return RecordingDevices(_p);
	}

	public int playoutDeviceName(short index, ReturnValue<String> device, 
			ReturnValue<String> guid) {
		OutputParam output = new OutputParam();
		int result = PlayoutDeviceName(_p, index, output);
		device.setValue((String) output.getObject()[0]);
		guid.setValue((String) output.getObject()[1]);
		return result;
	}

	public int recordingDeviceName(short index, ReturnValue<String> device, 
			ReturnValue<String> guid) {
		OutputParam output = new OutputParam();
		int result = RecordingDeviceName(_p, index, output);
		device.setValue((String) output.getObject()[0]);
		guid.setValue((String) output.getObject()[1]);
		return result;
	}

	// Device selection
	public int setPlayoutDevice(short index) {
		return SetPlayoutDevice(_p, index);
	}

	public int setPlayoutDevice(int device) {
		return SetPlayoutDevice2(_p, device);
	}

	public int setRecordingDevice(short index) {
		return SetRecordingDevice(_p, index);
	}

	public int setRecordingDevice(int device) {
		return SetRecordingDevice2(_p, device);
	}

	// Audio transport initialization
	public int playoutIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = PlayoutIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int initPlayout() {
		return InitPlayout(_p);
	}

	public boolean playoutIsInitialized() {
		return PlayoutIsInitialized(_p);
	}

	public int recordingIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = RecordingIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int initRecording() {
		return InitRecording(_p);
	}

	public boolean recordingIsInitialized() {
		return RecordingIsInitialized(_p);
	}

	// Audio transport control
	public int startPlayout() {
		return StartPlayout(_p);
	}

	public int stopPlayout() {
		return StopPlayout(_p);
	}

	public boolean playing() {
		return Playing(_p);
	}

	public int startRecording() {
		return StartRecording(_p);
	}

	public int stopRecording() {
		return StopRecording(_p);
	}

	public boolean recording() {
		return Recording(_p);
	}

	// Microphone Automatic Gain Control (AGC)
	public int setAGC(boolean enable) {
		return SetAGC(_p, enable);
	}

	public boolean getAGC() {
		return AGC(_p);
	}

	// Volume control based on the Windows Wave API (Windows only)
	public int setWaveOutVolume(short volumeLeft, short volumeRight) {
		return SetWaveOutVolume(_p, volumeLeft, volumeRight);
	}

	public int waveOutVolume(ReturnValue<Integer> volumeLeft, ReturnValue<Integer> volumeRight) {
		OutputParam output = new OutputParam();
		int result = WaveOutVolume(_p, output);
		volumeLeft.setValue((Integer) output.getObject()[0]);
		volumeRight.setValue((Integer) output.getObject()[1]);
		return result;
	}

	// Audio mixer initialization
	public int speakerIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = SpeakerIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int initSpeaker() {
		return InitSpeaker(_p);
	}

	public boolean speakerIsInitialized() {
		return SpeakerIsInitialized(_p);
	}

	public int microphoneIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = MicrophoneIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int initMicrophone() {
		return InitMicrophone(_p);
	}

	public boolean microphoneIsInitialized() {
		return MicrophoneIsInitialized(_p);
	}

	// Speaker volume controls
	public int speakerVolumeIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = SpeakerVolumeIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setSpeakerVolume(int volume) {
		return SetSpeakerVolume(_p, volume);
	}

	public int speakerVolume(ReturnValue<Integer> volume) {
		OutputParam output = new OutputParam();
		int result = SpeakerVolume(_p, output);
		volume.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int maxSpeakerVolume(ReturnValue<Integer> maxVolume) {
		OutputParam output = new OutputParam();
		int result = MaxSpeakerVolume(_p, output);
		maxVolume.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int minSpeakerVolume(ReturnValue<Integer> minVolume) {
		OutputParam output = new OutputParam();
		int result = MinSpeakerVolume(_p, output);
		minVolume.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int speakerVolumeStepSize(ReturnValue<Integer> stepSize) {
		OutputParam output = new OutputParam();
		int result = SpeakerVolumeStepSize(_p, output);
		stepSize.setValue((Integer) output.getObject()[0]);
		return result;
	}

	// Microphone volume controls
	public int microphoneVolumeIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = MicrophoneVolumeIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setMicrophoneVolume(int volume) {
		return SetMicrophoneVolume(_p, volume);
	}

	public int microphoneVolume(ReturnValue<Integer> volume) {
		OutputParam output = new OutputParam();
		int result = MicrophoneVolume(_p, output);
		volume.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int maxMicrophoneVolume(ReturnValue<Integer> maxVolume) {
		OutputParam output = new OutputParam();
		int result = MaxMicrophoneVolume(_p, output);
		maxVolume.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int minMicrophoneVolume(ReturnValue<Integer> minVolume) {
		OutputParam output = new OutputParam();
		int result = MinMicrophoneVolume(_p, output);
		minVolume.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int microphoneVolumeStepSize(ReturnValue<Integer> stepSize) {
		OutputParam output = new OutputParam();
		int result = MicrophoneVolumeStepSize(_p, output);
		stepSize.setValue((Integer) output.getObject()[0]);
		return result;
	}

	// Speaker mute control
	public int speakerMuteIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = SpeakerMuteIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setSpeakerMute(boolean enable) {
		return SetSpeakerMute(_p, enable);
	}

	public int speakerMute(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = SpeakerMute(_p, output);
		enabled.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	// Microphone mute control
	public int microphoneMuteIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = MicrophoneMuteIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setMicrophoneMute(boolean enable) {
		return SetMicrophoneMute(_p, enable);
	}

	public int microphoneMute(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = MicrophoneMute(_p, output);
		enabled.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	// Microphone boost control
	public int microphoneBoostIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = MicrophoneBoostIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setMicrophoneBoost(boolean enable) {
		return SetMicrophoneBoost(_p, enable);
	}

	public int microphoneBoost(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = MicrophoneBoost(_p, output);
		enabled.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	// Stereo support
	public int stereoPlayoutIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = StereoPlayoutIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setStereoPlayout(boolean enable) {
		return SetStereoPlayout(_p, enable);
	}

	public int stereoPlayout(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = StereoPlayout(_p, output);
		enabled.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int stereoRecordingIsAvailable(ReturnValue<Boolean> available) {
		OutputParam output = new OutputParam();
		int result = StereoRecordingIsAvailable(_p, output);
		available.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setStereoRecording(boolean enable) {
		return SetStereoRecording(_p, enable);
	}

	public int stereoRecording(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = StereoRecording(_p, output);
		enabled.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	public int setRecordingChannel(int channelType) {
		return SetRecordingChannel(_p, channelType);
	}

	public int recordingChannel(ReturnValue<ChannelType> channelType) {
		OutputParam output = new OutputParam();
		int result = RecordingChannel(_p, output);
		channelType.setValue(ChannelType.fromValue((Integer) output.getObject()[0]));
		return result;
	}

	// Delay information and control
	public int setPlayoutBuffer(int type, short sizeMS) {
		return SetPlayoutBuffer(_p, type, sizeMS);
	}

	public int playoutBuffer(ReturnValue<Integer> type, ReturnValue<Integer> sizeMS) {
		OutputParam output = new OutputParam();
		int result = PlayoutBuffer(_p, output);
		type.setValue((Integer) output.getObject()[0]);
		sizeMS.setValue((Integer) output.getObject()[1]);
		return result;
	}

	public int playoutDelay(ReturnValue<Integer> delayMS) {
		OutputParam output = new OutputParam();
		int result = PlayoutDelay(_p, output);
		delayMS.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int recordingDelay(ReturnValue<Integer> delayMS) {
		OutputParam output = new OutputParam();
		int result = RecordingDelay(_p, output);
		delayMS.setValue((Integer) output.getObject()[0]);
		return result;
	}

	// CPU load
	public int cpuLoad(ReturnValue<Integer> load) {
		OutputParam output = new OutputParam();
		int result = CPULoad(_p, output);
		load.setValue((Integer) output.getObject()[0]);
		return result;
	}

	// Recording of raw PCM data
	public int startRawOutputFileRecording(String pcmFileNameUTF8) {
		return StartRawOutputFileRecording(_p, pcmFileNameUTF8);
	}

	public int stopRawOutputFileRecording() {
		return StopRawOutputFileRecording(_p);
	}

	public int startRawInputFileRecording(String pcmFileNameUTF8) {
		return StartRawInputFileRecording(_p, pcmFileNameUTF8);
	}

	public int stopRawInputFileRecording() {
		return StopRawInputFileRecording(_p);
	}

	// Native sample rate controls (samples/sec)
	public int setRecordingSampleRate(int samplesPerSec) {
		return SetRecordingSampleRate(_p, samplesPerSec);
	}

	public int recordingSampleRate(ReturnValue<Integer> samplesPerSec) {
		OutputParam output = new OutputParam();
		int result = RecordingSampleRate(_p, output);
		samplesPerSec.setValue((Integer) output.getObject()[0]);
		return result;
	}

	public int setPlayoutSampleRate(int samplesPerSec) {
		return SetPlayoutSampleRate(_p, samplesPerSec);
	}

	public int playoutSampleRate(ReturnValue<Integer> samplesPerSec) {
		OutputParam output = new OutputParam();
		int result = PlayoutSampleRate(_p, output);
		samplesPerSec.setValue((Integer) output.getObject()[0]);
		return result;
	}

	// Mobile device specific functions
	public int resetAudioDevice() {
		return ResetAudioDevice(_p);
	}

	public int setLoudspeakerStatus(boolean enable) {
		return SetLoudspeakerStatus(_p, enable);
	}

	public int getLoudspeakerStatus(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetLoudspeakerStatus(_p, output);
		enabled.setValue((Boolean) output.getObject()[0]);
		return result;
	}

	protected AudioDeviceModule(long p) {
		_p = p;
	}

	protected long _p;
	
	
	//[end]
	
	
	
	
	
	
	
	
	
	
	
	
	

	// [start] jni api

	private static native long CreateAudioDeviceModule(int id, int audioLayer);

	// Retrieve the currently utilized audio layer
	private static native int ActiveAudioLayer(long p_AudioDeviceModule,
			OutputParam output);

	// Error handling
	private static native int LastError(long p_AudioDeviceModule);

	private static native int RegisterEventObserver(long p_AudioDeviceModule,
			AudioDeviceObserver eventCallback);

	// Full-duplex transportation of PCM audio
	private static native int RegisterAudioCallback(long p_AudioDeviceModule,
			AudioTransport audioCallback);

	// Main initialization and termination
	private static native int Init(long p_AudioDeviceModule);

	private static native int Terminate(long p_AudioDeviceModule);

	private static native boolean Initialized(long p_AudioDeviceModule);

	// Device enumeration
	private static native short PlayoutDevices(long p_AudioDeviceModule);

	private static native short RecordingDevices(long p_AudioDeviceModule);

	private static native int PlayoutDeviceName(long p_AudioDeviceModule,
			short index, OutputParam output);

	private static native int RecordingDeviceName(long p_AudioDeviceModule,
			short index, OutputParam output);

	// Device selection
	private static native int SetPlayoutDevice(long p_AudioDeviceModule,
			short index);

	private static native int SetPlayoutDevice2(long p_AudioDeviceModule,
			int device);

	private static native int SetRecordingDevice(long p_AudioDeviceModule,
			short index);

	private static native int SetRecordingDevice2(long p_AudioDeviceModule,
			int device);

	// Audio transport initialization
	private static native int PlayoutIsAvailable(long p_AudioDeviceModule,
			OutputParam available);

	private static native int InitPlayout(long p_AudioDeviceModule);

	private static native boolean PlayoutIsInitialized(long p_AudioDeviceModule);

	private static native int RecordingIsAvailable(long p_AudioDeviceModule,
			OutputParam available);

	private static native int InitRecording(long p_AudioDeviceModule);

	private static native boolean RecordingIsInitialized(
			long p_AudioDeviceModule);

	// Audio transport control
	private static native int StartPlayout(long p_AudioDeviceModule);

	private static native int StopPlayout(long p_AudioDeviceModule);

	private static native boolean Playing(long p_AudioDeviceModule);

	private static native int StartRecording(long p_AudioDeviceModule);

	private static native int StopRecording(long p_AudioDeviceModule);

	private static native boolean Recording(long p_AudioDeviceModule);

	// Microphone Automatic Gain Control (AGC)
	private static native int SetAGC(long p_AudioDeviceModule, boolean enable);

	private static native boolean AGC(long p_AudioDeviceModule);

	// Volume control based on the Windows Wave API (Windows only)
	private static native int SetWaveOutVolume(long p_AudioDeviceModule,
			short volumeLeft, short volumeRight);

	private static native int WaveOutVolume(long p_AudioDeviceModule,
			OutputParam output);

	// Audio mixer initialization
	private static native int SpeakerIsAvailable(long p_AudioDeviceModule,
			OutputParam available);

	private static native int InitSpeaker(long p_AudioDeviceModule);

	private static native boolean SpeakerIsInitialized(long p_AudioDeviceModule);

	private static native int MicrophoneIsAvailable(long p_AudioDeviceModule,
			OutputParam available);

	private static native int InitMicrophone(long p_AudioDeviceModule);

	private static native boolean MicrophoneIsInitialized(
			long p_AudioDeviceModule);

	// Speaker volume controls
	private static native int SpeakerVolumeIsAvailable(
			long p_AudioDeviceModule, OutputParam available);

	private static native int SetSpeakerVolume(long p_AudioDeviceModule,
			int volume);

	private static native int SpeakerVolume(long p_AudioDeviceModule,
			OutputParam volume);

	private static native int MaxSpeakerVolume(long p_AudioDeviceModule,
			OutputParam maxVolume);

	private static native int MinSpeakerVolume(long p_AudioDeviceModule,
			OutputParam minVolume);

	private static native int SpeakerVolumeStepSize(long p_AudioDeviceModule,
			OutputParam stepSize);

	// Microphone volume controls
	private static native int MicrophoneVolumeIsAvailable(
			long p_AudioDeviceModule, OutputParam available);

	private static native int SetMicrophoneVolume(long p_AudioDeviceModule,
			int volume);

	private static native int MicrophoneVolume(long p_AudioDeviceModule,
			OutputParam volume);

	private static native int MaxMicrophoneVolume(long p_AudioDeviceModule,
			OutputParam maxVolume);

	private static native int MinMicrophoneVolume(long p_AudioDeviceModule,
			OutputParam minVolume);

	private static native int MicrophoneVolumeStepSize(
			long p_AudioDeviceModule, OutputParam stepSize);

	// Speaker mute control
	private static native int SpeakerMuteIsAvailable(long p_AudioDeviceModule,
			OutputParam available);

	private static native int SetSpeakerMute(long p_AudioDeviceModule,
			boolean enable);

	private static native int SpeakerMute(long p_AudioDeviceModule,
			OutputParam enabled);

	// Microphone mute control
	private static native int MicrophoneMuteIsAvailable(
			long p_AudioDeviceModule, OutputParam available);

	private static native int SetMicrophoneMute(long p_AudioDeviceModule,
			boolean enable);

	private static native int MicrophoneMute(long p_AudioDeviceModule,
			OutputParam enabled);

	// Microphone boost control
	private static native int MicrophoneBoostIsAvailable(
			long p_AudioDeviceModule, OutputParam available);

	private static native int SetMicrophoneBoost(long p_AudioDeviceModule,
			boolean enable);

	private static native int MicrophoneBoost(long p_AudioDeviceModule,
			OutputParam enabled);

	// Stereo support
	private static native int StereoPlayoutIsAvailable(
			long p_AudioDeviceModule, OutputParam available);

	private static native int SetStereoPlayout(long p_AudioDeviceModule,
			boolean enable);

	private static native int StereoPlayout(long p_AudioDeviceModule,
			OutputParam enabled);

	private static native int StereoRecordingIsAvailable(
			long p_AudioDeviceModule, OutputParam available);

	private static native int SetStereoRecording(long p_AudioDeviceModule,
			boolean enable);

	private static native int StereoRecording(long p_AudioDeviceModule,
			OutputParam enabled);

	private static native int SetRecordingChannel(long p_AudioDeviceModule,
			int channelType);

	private static native int RecordingChannel(long p_AudioDeviceModule,
			OutputParam channelType);

	// Delay information and control
	private static native int SetPlayoutBuffer(long p_AudioDeviceModule,
			int type, short sizeMS);

	private static native int PlayoutBuffer(long p_AudioDeviceModule,
			OutputParam output);

	private static native int PlayoutDelay(long p_AudioDeviceModule,
			OutputParam delayMS);

	private static native int RecordingDelay(long p_AudioDeviceModule,
			OutputParam delayMS);

	// CPU load
	private static native int CPULoad(long p_AudioDeviceModule, OutputParam load);

	// Recording of raw PCM data
	private static native int StartRawOutputFileRecording(
			long p_AudioDeviceModule, String pcmFileNameUTF8);

	private static native int StopRawOutputFileRecording(
			long p_AudioDeviceModule);

	private static native int StartRawInputFileRecording(
			long p_AudioDeviceModule, String pcmFileNameUTF8);

	private static native int StopRawInputFileRecording(long p_AudioDeviceModule);

	// Native sample rate controls (samples/sec)
	private static native int SetRecordingSampleRate(long p_AudioDeviceModule,
			int samplesPerSec);

	private static native int RecordingSampleRate(long p_AudioDeviceModule,
			OutputParam samplesPerSec);

	private static native int SetPlayoutSampleRate(long p_AudioDeviceModule,
			int samplesPerSec);

	private static native int PlayoutSampleRate(long p_AudioDeviceModule,
			OutputParam samplesPerSec);

	// Mobile device specific functions
	private static native int ResetAudioDevice(long p_AudioDeviceModule);

	private static native int SetLoudspeakerStatus(long p_AudioDeviceModule,
			boolean enable);

	private static native int GetLoudspeakerStatus(long p_AudioDeviceModule,
			OutputParam enabled);

	// [end]

	static {
		try {
			System.loadLibrary("voice_engine_jni");
		} catch(UnsatisfiedLinkError e) {
			e.printStackTrace();
		}
	}
}
